﻿
using KZ.Utilities;
using System;
using System.Data;
using System.Linq;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
using KZ.Express.H.Presenter;
using KZ.Express.H.ENT;
using KZ.Express.H.BLL;

namespace KZ.Express.H.Presenter
{
    public interface IPriceDetailView : IBaseView
    {
        DataTable ZoneTypes { set; }

        DataTable TblDOX { get; set; }

        DataTable TblWPX { get; set; }
    }

    public class PriceDetailPresenter : BasePresenter, IBasePresenter
    {
        protected IPriceDetailView _priceDetailView;
        protected PriceListBLL _priceListBLL;

        public PriceDetailPresenter(IPriceDetailView view)
            : base(view)
        {
            _view = _priceDetailView = view;
            _baseBLL = _priceListBLL = new PriceListBLL();
        }

        public void LoadDataTable()
        {
            try
            {
                _priceDetailView.SetMessage(String.Empty);
                SearchCriteria search = new SearchCriteria();
                search.Add("PriceListID", _priceDetailView.EntityID);

                DataTable dtDOX = _priceDetailView.TblDOX;
                DataTable dox = _priceListBLL.LoadPriceListDetail(_priceDetailView.EntityID, "DOX");

                //// group by FromWeight to count how many rows
                var groupDOX = dox.AsEnumerable().GroupBy(p => p.Field<decimal>("FromWeight")).OrderBy(p => p.Key);
                foreach (var g in groupDOX)
                {
                    DataRow[] rows = dox.Select("FromWeight = " + g.Key);

                    DataRow r = dtDOX.NewRow();
                    decimal fromWeight = g.Key;
                    decimal toWeigth = Utility.DecimalParse(rows[0]["ToWeight"]);
                    if (fromWeight == toWeigth)
                        r["Weight"] = fromWeight.ToString("N1");
                    else
                        r["Weight"] = fromWeight.ToString("N1") + "-" + toWeigth.ToString("N1");

                    foreach (DataRow row in rows)
                    {
                        string zone = Utility.StringParse(row["Zone"]);
                        if (dtDOX.Columns.Contains(zone))
                            r[zone] = row["ListPrice"];
                    }
                    dtDOX.Rows.Add(r);
                }

                DataTable dtWPX = _priceDetailView.TblWPX;
                DataTable wpx = _priceListBLL.LoadPriceListDetail(_priceDetailView.EntityID, "WPX");

                //// group by FromWeight to count how many rows
                var groupWPX = wpx.AsEnumerable().GroupBy(p => p.Field<decimal>("FromWeight")).OrderBy(p => p.Key);
                foreach (var g in groupWPX)
                {
                    DataRow[] rows = wpx.Select("FromWeight = " + g.Key);

                    DataRow r = dtWPX.NewRow();
                    decimal fromWeight = g.Key;
                    decimal toWeigth = Utility.DecimalParse(rows[0]["ToWeight"]);
                    if (fromWeight == toWeigth)
                        r["Weight"] = fromWeight.ToString("N1");
                    else
                        r["Weight"] = fromWeight.ToString("N1") + "-" + toWeigth.ToString("N1");

                    foreach (DataRow row in rows)
                    {
                        string zone = Utility.StringParse(row["Zone"]);
                        if (dtDOX.Columns.Contains(zone))
                            r[zone] = row["ListPrice"];
                    }
                    dtWPX.Rows.Add(r);
                }

                _priceDetailView.TblDOX = dtDOX;
                _priceDetailView.TblWPX = dtWPX;
            }
            catch (DataAccessException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
        }

        public void LoadZoneDetail(int zoneID)
        {
            try
            {
                _priceDetailView.SetMessage(String.Empty);
                _priceDetailView.ZoneTypes = _priceListBLL.LoadZoneDetailType(zoneID);
            }
            catch (DataAccessException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
        }

        public void ImportExcel(string fileName, DataTable schema)
        {
            Excel.Application xlApp = null;
            Excel.Workbook xlWorkBook = null;
            Excel.Worksheet xlWorkSheet = null;
            Excel.Range range = null;

            try
            {
                xlApp = new Excel.Application();
                xlWorkBook = xlApp.Workbooks.Open(fileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, true,
                    Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
                xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);

                //// get a range to work with
                range = xlWorkSheet.get_Range("A3", Type.Missing);
                //// get the end of values toward the bottom, looking in the last column (will stop at first empty cell)
                range = range.get_End(Microsoft.Office.Interop.Excel.XlDirection.xlDown);
                //// get the address of the bottom cell
                string downAddress = range.get_Address(false, false, Microsoft.Office.Interop.Excel.XlReferenceStyle.xlA1, Type.Missing, Type.Missing);
                int end = Utility.IntParse(downAddress.Remove(0, 1));
                range = xlWorkSheet.get_Range("A1", "AA" + end);

                int rowCount = range.Rows.Count;
                int colCount = range.Columns.Count;

                _priceDetailView.UpdateValueProgressBar(0);
                _priceDetailView.ChangeProgressBarVisible(true);
                _priceDetailView.ChangeProgressBarMaximum(rowCount - 1);

                DataTable dtDOX = new DataTable();
                dtDOX.Columns.Add("Number", typeof(int));
                dtDOX.Columns.Add("Weight", typeof(string));

                DataTable dtWPX = new DataTable();
                dtWPX.Columns.Add("Number", typeof(int));
                dtWPX.Columns.Add("Weight", typeof(string));

                for (int i = 2; i <= colCount; i++)
                {
                    string colName = Utility.StringParse((object)(range.Cells[1, i] as Excel.Range).Value2);
                    if (schema.Columns.Contains(colName))
                    {
                        dtDOX.Columns.Add(colName, typeof(decimal));
                        dtWPX.Columns.Add(colName, typeof(decimal));
                    }
                }

                bool isDOX = true;
                for (int i = 2; i <= rowCount; i++)
                {
                    string weight = Utility.StringParse((object)(range.Cells[i, 1] as Excel.Range).Value2);
                    if (!String.IsNullOrEmpty(weight))
                    {
                        if (weight == "WPX")
                            isDOX = false;
                        else if (weight == "DOX")
                            isDOX = true;

                        if (weight != "WPX" && weight != "DOX")
                        {
                            DataRow row;
                            if (isDOX)
                            {
                                row = dtDOX.NewRow();
                                row["Number"] = dtDOX.Rows.Count + 1;
                            }
                            else
                            {
                                row = dtWPX.NewRow();
                                row["Number"] = dtWPX.Rows.Count + 1;
                            }

                            decimal? tmp = Utility.DecimalNParse(weight);
                            if (tmp.HasValue)
                                row["Weight"] = tmp.Value.ToString("N1");
                            else
                                row["Weight"] = weight;

                            for (int j = 2; j <= colCount; j++)
                            {
                                string column = Utility.StringParse((object)(range.Cells[1, j] as Excel.Range).Value2);
                                if (!String.IsNullOrWhiteSpace(column))
                                {
                                    string tmpValue = Utility.StringParse((object)(range.Cells[i, j] as Excel.Range).Value2);
                                    decimal? value = Utility.DecimalNParse(tmpValue);
                                    if (!String.IsNullOrEmpty(column))
                                    {
                                        if (value.HasValue)
                                            row[column] = value;
                                        else
                                            row[column] = DBNull.Value;
                                    }
                                }
                            }

                            if (isDOX)
                                dtDOX.Rows.Add(row);
                            else
                                dtWPX.Rows.Add(row);
                        }
                    }

                    _priceDetailView.PerformStepProgressBar(1);
                }

                _priceDetailView.TblDOX = dtDOX;
                _priceDetailView.TblWPX = dtWPX;
                _priceDetailView.UpdateValueProgressBar(rowCount - 1);
            }
            catch (Exception)
            {
                //Log.LogEx(Message.BLM_ERR_GENERAL.ToString(), Log.LogType.Error, ex);
            }
            finally
            {
                xlWorkBook.Close(false, Type.Missing, Type.Missing);
                xlApp.Quit();

                System.Threading.Thread.Sleep(1000);

                if (range != null) Marshal.ReleaseComObject(range);
                if (xlWorkSheet != null) Marshal.ReleaseComObject(xlWorkSheet);
                if (xlWorkBook != null) Marshal.ReleaseComObject(xlWorkBook);
                if (xlApp != null) Marshal.ReleaseComObject(xlApp);
                range = null;
                xlWorkSheet = null;
                xlWorkBook = null;
                xlApp = null;

                _priceDetailView.ChangeProgressBarVisible(false);
            }
        }
    }

    public class OriginalPriceDetailPresenter : PriceDetailPresenter
    {
        public OriginalPriceDetailPresenter(IPriceDetailView view)
            : base(view)
        {
        }

        public override void Save()
        {
            PriceListENT priceList = _priceDetailView.Entity as PriceListENT;
            priceList.IsRecovery = _isRecovery;
            try
            {
                _priceDetailView.EntityID = _priceListBLL.Save(priceList, _priceDetailView.TblDOX, _priceDetailView.TblWPX);
                if (_priceDetailView.ActionName == "Insert")
                    _priceDetailView.Entity = null;
                _isRecovery = 0;
                _priceDetailView.SetMessage("Dữ liệu đã lưu thành công");
            }
            catch (DataAccessException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
            catch (BusinessLogicException ex)
            {
                if (priceList.IsRecovery == 1)
                {
                    if (_priceDetailView.ShowMessageConfirm(ex.Message))
                        _isRecovery = 1;
                    else
                        _isRecovery = 2;

                    Save();
                }
                else
                    throw new BusinessLogicException(ex.Message);
            }
        }
    }

}